package com.ruoyi.leave.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.info.domain.InfoClass;
import com.ruoyi.info.domain.InfoGrade;
import com.ruoyi.info.domain.InfoMajor;
import com.ruoyi.info.domain.InfoStu;
import com.ruoyi.info.mapper.InfoClassMapper;
import com.ruoyi.info.mapper.InfoGradeMapper;
import com.ruoyi.info.mapper.InfoMajorMapper;
import com.ruoyi.info.mapper.InfoStuMapper;
import com.ruoyi.leave.domain.LeaveApplyCourse;
import com.ruoyi.leave.domain.vo.LeaveCount;
import org.checkerframework.checker.units.qual.A;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import org.apache.commons.lang3.StringUtils;
import com.ruoyi.leave.mapper.LeaveApplyMapper;
import com.ruoyi.leave.domain.LeaveApply;
import com.ruoyi.leave.service.ILeaveApplyService;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.TransactionDefinition;
import org.springframework.transaction.TransactionStatus;
import org.springframework.transaction.support.DefaultTransactionDefinition;

import java.util.ArrayList;
import java.util.List;

import static com.ruoyi.common.utils.DateUtils.getNowDate;
import static com.ruoyi.common.utils.SecurityUtils.getUsername;

/**
 * 请假申请Service业务层处理
 *
 * @author ruoyi
 * @date 2024-09-24
 */
@Service
public class LeaveApplyServiceImpl extends ServiceImpl<LeaveApplyMapper, LeaveApply> implements ILeaveApplyService {

    @Autowired
    LeaveApplyMapper _leaveApplyMapper;

    @Autowired
    LeaveApplyCourseServiceImpl _leaveApplyCourseService;

    @Autowired
    InfoClassMapper _infoClassMapper;

    @Autowired
    InfoStuMapper _infoStuMapper;

    @Autowired
    InfoMajorMapper _infoMajorMapper;

    @Autowired
    InfoGradeMapper _infoGradeMapper;

    @Autowired
    public PlatformTransactionManager transactionManager;

    @Override
    public AjaxResult listCourse(Long applyId){
        try{
            QueryWrapper<LeaveApplyCourse> wrapper = new QueryWrapper<>();
            wrapper.eq("apply_id", applyId);
            List<LeaveApplyCourse> list = _leaveApplyCourseService.list(wrapper);
            return AjaxResult.success(list);
        }catch(Exception ex){
            return AjaxResult.error(ex.getMessage());
        }
    }


    @Override
    public AjaxResult countFdyUnAudit(){
        try{
            LeaveApply param = new LeaveApply();
            param.setApplyStatus("1");
            param.setTeacherNo(getUsername());
            List<LeaveApply> list = _leaveApplyMapper.listView(param);
            int res = list.size();

            return AjaxResult.success(res);
        }catch(Exception ex){
            return AjaxResult.error(ex.getMessage());
        }
    }



    @Override
    public AjaxResult doAudit( LeaveApply param){
        try{

            LeaveApply leaveApply = _leaveApplyMapper.selectById(param.getId());
            if(leaveApply == null){
                return AjaxResult.error("未找到该请假申请");
            }

            leaveApply.applyStatus = param.applyStatus;

            if (param.applyStatus.equals("11")){
                leaveApply.returnMsg = param.returnMsg;
            }

            if(leaveApply.fdyCmt == null || leaveApply.fdyCmt.equals("")){
                leaveApply.fdyCmt = param.fdyCmt;
                leaveApply.fdyNo = getUsername();
            }else{
                if(leaveApply.deptCmt == null || leaveApply.deptCmt.equals("")){
                    leaveApply.deptCmt = param.deptCmt;
                    leaveApply.deptNo = getUsername();
                }
            }
            

            int res = _leaveApplyMapper.updateById(leaveApply);
            if(res == 0){
                throw new Exception("更新审核状态失败");
            }

            return AjaxResult.success();
        }catch (Exception e){
            return AjaxResult.error(e.getMessage());
        }
    }


    @Override
    public AjaxResult cancelApply(Long id){
        try{
            LeaveApply leaveApply = _leaveApplyMapper.selectById(id);
            if(leaveApply == null){
                return AjaxResult.error("未找到该请假申请");
            }
            if(!leaveApply.getStuNo().equals(getUsername())){
                throw new Exception("不是该请假申请的申请人");
            }
            if(!leaveApply.getApplyStatus().equals("1")){
                return AjaxResult.error("该请假申请已被审核");
            }

            int res = _leaveApplyMapper.deleteById(id);
            if(res == 0){
                throw new Exception("取消失败");
            }

            return AjaxResult.success();
        }catch(Exception ex){
            return AjaxResult.error(ex.getMessage());
        }
    }



    @Override
    public AjaxResult getOwnApply( Long id){
        try{
            LeaveApply leaveApply = _leaveApplyMapper.selectById(id);
            if(leaveApply == null){
                return AjaxResult.error("未找到该请假申请");
            }
            if(!leaveApply.getStuNo().equals(getUsername())){
                throw new Exception("不是该请假申请的申请人");
            }
            return AjaxResult.success(leaveApply);
        }catch(Exception ex){
            return AjaxResult.error(ex.getMessage());
        }
    }


    @Override
    public List<LeaveCount> listCount(LeaveApply leaveApply){
        return _leaveApplyMapper.listCount(leaveApply);
    }


    @Override
    public List<LeaveApply> listView(LeaveApply leaveApply){
        return _leaveApplyMapper.listView(leaveApply);
    }


    @Override
    public AjaxResult doApply(LeaveApply param){
        TransactionDefinition def = new DefaultTransactionDefinition();
        TransactionStatus status = transactionManager.getTransaction(def);
        try{
            String stuNo = getUsername();
            QueryWrapper<InfoStu> stuQueryWrapper = new QueryWrapper<>();
            stuQueryWrapper.eq("stu_no", stuNo);
            InfoStu infoStu = _infoStuMapper.selectOne(stuQueryWrapper);
            if(infoStu == null){
                throw new Exception("未找到该学生信息");
            }

            String classCode = infoStu.getClassCode();
            QueryWrapper<InfoClass> classQueryWrapper = new QueryWrapper<>();
            classQueryWrapper.eq("class_code", classCode);
            InfoClass infoClass = _infoClassMapper.selectOne(classQueryWrapper);
            if(infoClass == null){
                throw new Exception("未找到该班级信息");
            }

            String gradeCode = infoClass.getGradeCode();
            if(gradeCode == null || gradeCode.equals("")){
                throw new Exception("未找到该班级的年级信息");
            }
            QueryWrapper<InfoGrade> gradeQueryWrapper = new QueryWrapper<>();
            gradeQueryWrapper.eq("grade_code", gradeCode);
            InfoGrade infoGrade = _infoGradeMapper.selectOne(gradeQueryWrapper);
            if(infoGrade == null){
                throw new Exception("未找到该年级信息");
            }

            String majorCode = infoClass.getMajorCode();
            if(majorCode == null || majorCode.equals("")){
                throw new Exception("未找到该班级的专业信息");
            }

            QueryWrapper<InfoMajor> majorQueryWrapper = new QueryWrapper<>();
            majorQueryWrapper.eq("major_code", majorCode);
            InfoMajor infoMajor = _infoMajorMapper.selectOne(majorQueryWrapper);
            if(infoMajor == null){
                throw new Exception("未找到该专业信息");
            }

            param.setGrade(infoGrade.getGradeName());
            param.setMajor(infoMajor.getMajorName());


            List<String> statusList = new ArrayList<String>();
            statusList.add("1");

            QueryWrapper<LeaveApply> queryWrapper = new QueryWrapper<>();
            queryWrapper.eq("stu_no", getUsername());
            queryWrapper.in("apply_status", statusList);
            List<LeaveApply> list = _leaveApplyMapper.selectList(queryWrapper);
            if(list.size() > 0){
                return AjaxResult.error("请假申请已存在，请勿重复申请");
            }

            param.setStuNo(getUsername());
            param.applyTime = getNowDate();
            param.applyStatus = "1";

            int res = _leaveApplyMapper.insert(param);

            if(res == 0){
                throw new Exception("申请失败");
            }

            List<LeaveApplyCourse> courseList = param.courseList;

            if(courseList!= null &&  courseList.size() > 0){
                courseList.forEach(course -> {
                    course.setApplyId(param.getId());
                });

                boolean res2 = _leaveApplyCourseService.saveBatch(courseList);
                if(!res2){
                    throw new Exception("涉及课程信息保存失败");
                }
            }


            transactionManager.commit(status);
            return AjaxResult.success();
        }catch(Exception ex){
            transactionManager.rollback(status);
            return AjaxResult.error(ex.getMessage());
        }
    }



    @Override
    public List<LeaveApply> queryList(LeaveApply leaveApply) {
        LambdaQueryWrapper<LeaveApply> lqw = Wrappers.lambdaQuery();
        if (StringUtils.isNotBlank(leaveApply.getStuNo())){
            lqw.eq(LeaveApply::getStuNo ,leaveApply.getStuNo());
        }
        if (leaveApply.getApplyTime() != null){
            lqw.eq(LeaveApply::getApplyTime ,leaveApply.getApplyTime());
        }
        if (StringUtils.isNotBlank(leaveApply.getApplyStatus())){
            lqw.eq(LeaveApply::getApplyStatus ,leaveApply.getApplyStatus());
        }
        if (StringUtils.isNotBlank(leaveApply.getGrade())){
            lqw.eq(LeaveApply::getGrade ,leaveApply.getGrade());
        }
        if (StringUtils.isNotBlank(leaveApply.getMajor())){
            lqw.eq(LeaveApply::getMajor ,leaveApply.getMajor());
        }
        if (StringUtils.isNotBlank(leaveApply.getReason())){
            lqw.eq(LeaveApply::getReason ,leaveApply.getReason());
        }
        if (leaveApply.getStartTime() != null){
            lqw.eq(LeaveApply::getStartTime ,leaveApply.getStartTime());
        }
        if (leaveApply.getEndTime() != null){
            lqw.eq(LeaveApply::getEndTime ,leaveApply.getEndTime());
        }
        if (StringUtils.isNotBlank(leaveApply.getToAddr())){
            lqw.eq(LeaveApply::getToAddr ,leaveApply.getToAddr());
        }
        if (StringUtils.isNotBlank(leaveApply.getParentName())){
            lqw.like(LeaveApply::getParentName ,leaveApply.getParentName());
        }
        if (StringUtils.isNotBlank(leaveApply.getCommit())){
            lqw.eq(LeaveApply::getCommit ,leaveApply.getCommit());
        }
        if (StringUtils.isNotBlank(leaveApply.getPhone())){
            lqw.eq(LeaveApply::getPhone ,leaveApply.getPhone());
        }
        if (StringUtils.isNotBlank(leaveApply.getToPeople())){
            lqw.eq(LeaveApply::getToPeople ,leaveApply.getToPeople());
        }
        if (StringUtils.isNotBlank(leaveApply.getToPhone())){
            lqw.eq(LeaveApply::getToPhone ,leaveApply.getToPhone());
        }
        if (StringUtils.isNotBlank(leaveApply.getFdySign())){
            lqw.eq(LeaveApply::getFdySign ,leaveApply.getFdySign());
        }
        if (StringUtils.isNotBlank(leaveApply.getFdyNo())){
            lqw.eq(LeaveApply::getFdyNo ,leaveApply.getFdyNo());
        }
        if (leaveApply.getFdyTime() != null){
            lqw.eq(LeaveApply::getFdyTime ,leaveApply.getFdyTime());
        }
        if (StringUtils.isNotBlank(leaveApply.getDeptSign())){
            lqw.eq(LeaveApply::getDeptSign ,leaveApply.getDeptSign());
        }
        if (StringUtils.isNotBlank(leaveApply.getDeptNo())){
            lqw.eq(LeaveApply::getDeptNo ,leaveApply.getDeptNo());
        }
        if (leaveApply.getDeptTime() != null){
            lqw.eq(LeaveApply::getDeptTime ,leaveApply.getDeptTime());
        }
        if (leaveApply.getTakingTime() != null){
            lqw.eq(LeaveApply::getTakingTime ,leaveApply.getTakingTime());
        }
        if (StringUtils.isNotBlank(leaveApply.getTakingSign())){
            lqw.eq(LeaveApply::getTakingSign ,leaveApply.getTakingSign());
        }
        if (StringUtils.isNotBlank(leaveApply.getTakingMaterial())){
            lqw.eq(LeaveApply::getTakingMaterial ,leaveApply.getTakingMaterial());
        }
        return this.list(lqw);
    }

}